"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具创建软连接
Create At   : 2023/4/19
Owner       : opentestcase019
Description :
    1.创建软连接，指定-s src_path和-t target_path参数为正常值
    2.创建软连接，指定src_path参数为不符合规范的路径
    3.创建软连接，指定target_path参数为不符合规范的文件名
    4.创建软连接，指定-U UDS:socket_domain参数为正常值
    5.创建软连接，指定错误的-U UDS:socket_domain参数
    6.创建软连接，指定权限不足的socket_domain
    7.在备机点执行创建软连接;expect:创建软连接成功
    8.环境清理
Expect      :
    1.创建软连接成功
    2.合理报错
    3.合理报错
    4.创建软连接成功
    5.合理报错Failed to get uds connection.
    6.合理报错Failed to get uds connection.
    7.创建软连接成功
    8.清理成功
History     :
"""
import os
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.dir_name = "dir_dsscmd_0027"
        self.file_name = "file_dsscmd_0027"
        self.file_name_63chars = \
            "file_dsscmd_0027_file_dsscmd_0027_file_dsscmd_0027_file_63chars"
        self.file_name_numbers = "0027"
        self.file_name_letters = "filedsscmd"
        self.link_name = [f"link_dsscmd_0027_{i}" for i in range(1, 7)]
        self.link_name_63chars = \
            "link_dsscmd_0027_link_dsscmd_0027_link_dsscmd_0027_link_63chars"
        self.link_name_64chars = \
            "link_dsscmd_0027_link_dsscmd_0027_link_dsscmd_0027_link1_64chars"
        self.link_name_numbers = "0027"
        self.link_name_letters = "linkdsscmd"
        self.logger.info("-----获取卷组名-----")
        cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(cmd)
        cmd_res = self.common.get_sh_result(self.primary_node, cmd)
        self.assertIn("Succeed to display lsvg info.", cmd_res,
                      "获取卷组名失败")
        self.vgname = cmd_res.splitlines()[1].split()[0].strip()
        self.logger.info(self.vgname)
        self.dir_path = os.path.join(self.vgname, self.dir_name)
        self.file_path = os.path.join(self.dir_path, self.file_name)
        self.file_path_63chars = os.path.join(self.dir_path,
                                              self.file_name_63chars)
        self.file_path_numbers = os.path.join(self.dir_path,
                                              self.file_name_numbers)
        self.file_path_letters = os.path.join(self.dir_path,
                                              self.file_name_letters)
        self.link_path = [os.path.join(self.vgname, i) for i in self.link_name]
        self.link_path_63chars = os.path.join(self.vgname,
                                              self.link_name_63chars)
        self.link_path_numbers = os.path.join(self.vgname,
                                              self.link_name_numbers)
        self.link_path_letters = os.path.join(self.vgname,
                                              self.link_name_letters)
        self.link_path_64chars = os.path.join(self.vgname,
                                              self.link_name_64chars)

    def test_sharestorage_tool(self):
        step1 = "-----step1:创建软连接，指定-s src_path和-t target_path参数" \
                "为正常值;expect:创建软连接成功-----"
        self.logger.info(step1)
        self.logger.info('----- 预置目录和文件 -----')
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
                      f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f'Succeed to make dir, path is +{self.vgname}, dir name '
                      f'is {self.dir_name}.', execute_msg, "执行失败" + step1)
        cmd_list = [self.file_path, self.file_path_63chars,
                    self.file_path_numbers, self.file_path_letters]
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd touch -p +{cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            self.assertIn(f"Succeed to create file, name is +{cmd}.",
                          execute_msg, "执行失败" + step1)
        cmd_dict = {f'{self.file_path}': f'{self.link_path[0]}',
                    f'{self.file_path_letters}': f'{self.link_path_letters}',
                    f'{self.file_path_numbers}': f'{self.link_path_numbers}',
                    f'{self.file_path_63chars}': f'{self.link_path_63chars}',
                    f'{self.file_path}$#': f'{self.link_path[1]}',
                    f'{self.file_path}_not_exists': f'{self.link_path[2]}',
                    f'{self.dir_path}': f'{self.link_path[3]}'}
        self.logger.info('----- 创建软链接 -----')
        for file, link in cmd_dict.items():
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                          f"dsscmd ln -s +{file} -t +{link}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if file == f'{self.file_path}$#':
                self.assertIn(f"Success to link +{link} "
                              f"to +data/dir_dsscmd_0027/file_dsscmd_00270",
                              execute_msg, "执行失败" + step1)
            else:
                self.assertIn(f"Success to link +{link} to +{file}.",
                              execute_msg, "执行失败" + step1)
        ls_cmd = f"source {macro.DB_ENV_PATH}; dsscmd ls -p +{self.vgname}"
        self.common.get_sh_result(self.primary_node, ls_cmd)

        step2 = "-----step2:创建软连接，指定src_path参数为不符合规范的路径;" \
                "expect:合理报错-----"
        self.logger.info(step2)
        cmd_list = [f'+{self.file_path}@#%', f'+{self.file_path}文件',
                    f'{self.file_path}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                          f"dsscmd ln -s {cmd} -t +{self.link_path[4]}"
            self.logger.info(execute_cmd)
            res = self.common.get_sh_result(self.primary_node,
                                            execute_cmd)
            if cmd == cmd_list[-1]:
                self.assertIn("decode error , path should start with +.",
                              res, "执行失败" + step2)
            else:
                self.assertIn("decode error , path should be "
                              "[0~9,a~z,A~Z,-,_,/,.]", res, "执行失败" + step2)

        step3 = "-----step3:创建软连接，指定target_path参数为不符合规范的文件名;expect:合理报错-----"
        self.logger.info(step3)
        cmd_list = [f'+{self.link_path[4]}@#', f'+{self.link_path_64chars}',
                    f'+{self.link_path[4]}软连接', f'+{self.link_path[3]}',
                    f'{self.link_path[4]}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                          f"dsscmd ln -s +{self.file_path} -t {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd == cmd_list[1]:
                self.assertIn("Fail to create symbolic link, reason the "
                              "length of name is too long", execute_msg,
                              "执行失败" + step3)
            elif cmd == cmd_list[-1]:
                self.assertIn("decode error , path should start with +.",
                              execute_msg, "执行失败" + step3)
            elif cmd == cmd_list[-2]:
                self.assertIn(f"Make dir or Create file failed, "
                              f"{self.link_name[3]} has already existed",
                              execute_msg, "执行失败" + step3)
            else:
                self.assertIn("decode error , path should be "
                              "[0~9,a~z,A~Z,-,_,/,.]",
                              execute_msg, "执行失败" + step3)

        step4 = "-----step4:创建软连接，指定-U UDS:socket_domain参数为正常值;" \
                "expect:创建软连接成功-----"
        self.logger.info(step4)
        cmd = f"source {macro.DB_ENV_PATH};" \
              f"dsscmd ln -s +{self.file_path} -t +{self.link_path[4]} " \
              f"-U {macro.UDS_PATH}"
        self.logger.info(cmd)
        cmd_res = self.common.get_sh_result(self.primary_node, cmd)
        self.assertIn(f"Success to link +{self.link_path[4]} "
                      f"to +{self.file_path}.", cmd_res, "执行失败" + step4)

        step5 = "-----step5:创建软连接，指定错误的-U UDS:socket_domain参数;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step5)
        cmd = f"source {macro.DB_ENV_PATH};" \
              f"dsscmd ln -s +{self.file_path} -t +{self.link_path[5]}  " \
              f"-U {macro.UDS_PATH}.cfg"
        self.logger.info(cmd)
        cmd_res = self.common.get_sh_result(self.primary_node, cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection, cmd_res,
                      "执行失败" + step5)

        step6 = "-----step6:创建软连接，指定权限不足的socket_domain;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step6)
        cmd = f"source {macro.DB_ENV_PATH};" \
              f"chmod 000 {macro.UDS_PATH[4::]};" \
              f"dsscmd ln -s +{self.file_path} -t +{self.link_path[5]} " \
              f"-U {macro.UDS_PATH};" \
              f"chmod 600 {macro.UDS_PATH[4::]}"
        self.logger.info(cmd)
        cmd_res = self.common.get_sh_result(self.primary_node, cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection, cmd_res,
                      "执行失败" + step6)

        step7 = "-----step7:在备机点执行创建软连接;expect:创建软连接成功-----"
        self.logger.info(step7)
        cmd = f"source {macro.DB_ENV_PATH};" \
              f"dsscmd ln -s +{self.file_path} -t +{self.link_path[5]} " \
              f"-U {macro.UDS_PATH}"
        self.logger.info(cmd)
        cmd_res = self.common.get_sh_result(self.standby_node, cmd)
        self.assertIn(f"Success to link +{self.link_path[5]} "
                      f"to +{self.file_path}.", cmd_res, "执行失败" + step7)

    def tearDown(self):
        step8 = "-----step8:环境清理;expect:清理成功-----"
        self.logger.info(step8)
        cmd = f'''source {macro.DB_ENV_PATH};
        dsscmd unlink -p +{self.link_path[0]}; 
        dsscmd unlink -p +{self.link_path[1]}; 
        dsscmd unlink -p +{self.link_path[2]}; 
        dsscmd unlink -p +{self.link_path[3]}; 
        dsscmd unlink -p +{self.link_path[4]}; 
        dsscmd unlink -p +{self.link_path[5]}; 
        dsscmd unlink -p +{self.link_path_63chars}; 
        dsscmd unlink -p +{self.link_path_numbers}; 
        dsscmd unlink -p +{self.link_path_letters}; 
        dsscmd unlink -p +{self.link_path_64chars[0:-1]}; 
        dsscmd rmdir -p +{self.dir_path} -r;'''
        self.logger.info(cmd)
        cmd_res = self.common.get_sh_result(self.primary_node, cmd)
        self.assertEquals(9, cmd_res.count("Succeed to unlink"), "删除软链接失败")
        self.assertIn(f"Failed to unlink +{self.link_path_64chars[0:-1]}",
                      cmd_res, "执行失败" + step8)
        self.assertIn(f"Succeed to rm dir, path is +{self.dir_path}",
                      cmd_res, "执行失败" + step8)
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
